/* CSci4061 F2012 Assignment 3
 * section: 3
 * date: 11/10/12
 * name: Jeff Goin, Jack Jones
 * id: 2999885, 4220764 */

#include "packet_public.h"
#include <string.h>

message_t message;     /* current message structure */
mm_t MM;               /* memory manager will allocate memory for packets */
int pkt_cnt = 0;       /* how many packets have arrived for current message */
int pkt_total = 1;     /* how many packets to be received for the message */
int NumMessages = 5;   /* number of messages we will receive */
int cnt_msg=1;         /*current message being received*/

packet_t get_packet (size) {
	packet_t pkt;
	static int which;

	pkt.how_many = size;
	which=rand()%pkt.how_many; //the order in which packets will be sent is random.
	pkt.which = which;
	if (which == 0)
	        strcpy (pkt.data, "aaaaaaa\0");
	else if (which == 1)
		strcpy (pkt.data, "bbbbbbb\0");
	else if(which == 2)
		strcpy (pkt.data, "ccccccc\0");
	else if(which == 3)
		strcpy (pkt.data, "ddddddd\0");
	else
		strcpy (pkt.data, "eeeeeee\0");
	return pkt;
}


void packet_handler(int sig)
{
	packet_t pkt;
	char *message_str;
	fprintf (stderr, "IN PACKET HANDLER, sig=%d\n", sig);

	pkt = get_packet(cnt_msg); // the messages are of variable length.
	pkt_total = pkt.how_many;

	if (pkt_cnt == 0){ // 1st packet arrives, the size of the whole message allocated.
	        message_str = (char *)malloc(pkt_total * sizeof(char) * 8);
		if (message_str == NULL)
		        perror("Malloc failed to allocate message string");
	} 
  
	printf("CURRENT MESSAGE %d\n",cnt_msg);

	/* stick packet in memory, handle duplicates */
	if (pkt.which == pkt_cnt){ 
	        message.data[pkt.which] = (char *)mm_get(&MM, 8);
		strncpy(message.data[pkt.which], pkt.data, 8);
		pkt_cnt++;
	}
	/*Print the packets.*/
	if (pkt_cnt == pkt_total){
	        int i = 0;
		while(i < pkt_total){
		        strcat(message_str, message.data[i]);
			mm_put(&MM, message.data[i]);
			i++;
		}
		printf("Message: %s\n", message_str);

		/*Deallocate message*/
		free(message_str);
	}
}


int main (int argc, char **argv)
{          
	/* set up alarm handler -- mask all signals within it */
	struct sigaction act;
	act.sa_handler = packet_handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	if (sigaction(SIGALRM, &act, NULL) == -1)
	        perror("Alarm handler not set");
   
	/* turn on alarm timer ... use  INTERVAL and INTERVAL_USEC for sec and usec values */
	struct itimerval interval;
        interval.it_interval.tv_sec = INTERVAL;
        interval.it_interval.tv_usec = INTERVAL_USEC;
	interval.it_value.tv_sec = INTERVAL;
	interval.it_value.tv_usec = INTERVAL_USEC;
	if (setitimer(ITIMER_REAL, &interval, NULL) == -1)
	        perror("Timer not set");
	
	message.num_packets = 0;
	mm_init (&MM, 200);
	int j;	
	
	for (j=1; j<=NumMessages; j++) {
	        while (pkt_cnt < pkt_total) 
			pause();
		// reset these for next message 
		pkt_total = 1;
		pkt_cnt = 0;
		message.num_packets = 0;
		cnt_msg++;
	}
	/* Deallocate memory manager */
	mm_release(&MM);
}
